"Masonry Layout"
Bootstrap 4.1.1 Snippet by ALIMUL AL RAZY

<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <!------ Include the above in your HEAD tag ----------> <div id="masonry-effect"> <div class="item" style="height: 400px;"><a href="https://fjolt.com/article/css-grid-masonry" target="_blank">View Article</a></div> <div class="item" style="height: 200px;">Item 2</div> <div class="item" style="height: 350px;">Item 3</div> <div class="item" style="height: 210px;">Item 4</div> <div class="item" style="height: 600px;">Item 5</div> <div class="item" style="height: 320px;">Item 6</div> <div class="item" style="height: 80px;">Item 7</div> <div class="item" style="height: 450px;">Item 8</div> <div class="item" style="height: 600px;">Item 9</div> <div class="item" style="height: 320px;">Item 10</div> <div class="item" style="height: 80px;">Item 11</div> <div class="item" style="height: 450px;">Item 12</div> </div> <script> let mainId = 'masonry-effect'; let itemIdentifier = '#masonry-effect .item'; document.addEventListener('DOMContentLoaded', function(e) { // Programmatically get the column width let item = document.querySelector(itemIdentifier); let parentWidth = item.parentNode.getBoundingClientRect().width; let itemWidth = item.getBoundingClientRect().width + parseFloat(getComputedStyle(item).marginLeft) + parseFloat(getComputedStyle(item).marginRight); let columnWidth = Math.round((1 / (itemWidth / parentWidth))); // We need this line since JS nodes are dumb let arrayOfItems = Array.prototype.slice.call( document.querySelectorAll(itemIdentifier) ); let trackHeights = {}; arrayOfItems.forEach(function(item) { // Get index of item let thisIndex = arrayOfItems.indexOf(item); // Get column this and set width let thisColumn = thisIndex % columnWidth; if(typeof trackHeights[thisColumn] == "undefined") { trackHeights[thisColumn] = 0; } trackHeights[thisColumn] += item.getBoundingClientRect().height + parseFloat(getComputedStyle(item).marginBottom); // If the item has an item above it, then move it to fill the gap if(thisIndex - columnWidth >= 0) { let getItemAbove = document.querySelector(`${itemIdentifier}:nth-of-type(${thisIndex - columnWidth + 1})`); let previousBottom = getItemAbove.getBoundingClientRect().bottom; let currentTop = item.getBoundingClientRect().top - parseFloat(getComputedStyle(item).marginBottom); item.style.top = `-${currentTop - previousBottom}px`; } }); let max = Math.max(...Object.values(trackHeights)); document.getElementById(mainId).style.height = `${max}px`; }); </script>
#masonry-effect { display: flex; flex-direction: row; flex-wrap: wrap; } a { color: white; font-size: 2rem; font-weight: 800; } .item { flex-direction: column; margin-right: 1.5rem; margin-bottom: 1.5rem; color: white; position: relative; width: calc(33.3% - 1.5rem); background: linear-gradient(45deg, #281dd4, #a42bff); border-radius: 12px; padding: 1rem; font-size: 1.25rem; box-sizing: border-box; font-variation-settings: 'wght' 600; } .item:nth-of-type(5) { background: linear-gradient(45deg, #d4581d, #ffbe2b); } .item:nth-of-type(3) { background: linear-gradient(45deg, #d41d71, #a42bff); } .item:nth-of-type(1) { background: linear-gradient(45deg, #1d5ed4, #2bbbff); } .item:nth-of-type(9), .item:nth-of-type(7) { background: linear-gradient(45deg, #85d41d, #2bd8ff); } body { background: black; padding: 3rem; }

Related: See More


Questions / Comments: